//
// Created by LiuYou on 2021/12/7.
//

#include <iostream>
#include <memory>
#include <utility>


// 放在头文件中...
class People {
public:
    People(const std::string& name, int age, const std::string& strongPoint);

    ~People();

//protected:
public:
    // todo 笔记: 注意: 这个 Impl 类的访问权限, 在重载流输出运算符的时候会出错！在 NestedClass4 中我会继续进行讨论。
    class Impl;

private:
//public:
    std::unique_ptr<Impl> pImpl;

public:
    friend std::ostream& operator<<(std::ostream& os, const People& people);
};

// ...放在头文件中。


// 放在实现文件中...
class People::Impl {
public:
    std::string name;
    int age;
    std::string strongPoint;

public:
    Impl(std::string name, int age, std::string strongPoint) :
            name( std::move( name )), age( age ), strongPoint( std::move( strongPoint )) {}

public:
//    friend std::ostream& operator<<(std::ostream& os, const Impl& rhs);
    friend std::ostream& operator<<(std::ostream& os, const Impl& rhs);
};

std::ostream& operator<<(std::ostream& os, const People::Impl& rhs) {
    os << "name: " << rhs.name << " age: " << rhs.age << " strongPoint: " << rhs.strongPoint;
    return os;
}

People::People(const std::string& name, int age, const std::string& strongPoint) :
        pImpl( std::make_unique<Impl>( name, age, strongPoint )) {}

People::~People() = default;


std::ostream& operator<<(std::ostream& os, const People& people) {
//        os << "pImpl: " << people.pImpl;
    os << "People: " << *people.pImpl;
    return os;
}

//std::ostream& People::Impl::operator<<(std::ostream& os, const People::Impl& rhs) {
//    os << "name: " << rhs.name << " age: " << rhs.age << " strongPoint: " << rhs.strongPoint;
//    return os;
//}


// ...放在实现文件中。


int main(int argc, char** argv) {
    People people( "留攸", 21, "无" );
//    std::cout << *people.pImpl << std::endl;

    std::cout << people << std::endl;


    return 0;
}
